//
//  WmcRecognitionResultVC.swift
//  YPWatermarkCamera
//
//  Created by 周诗松 on 2022/10/19.
//

import SVProgressHUD
import UIKit
import YPBedrock

// MARK: - 扩展WmcRecognitionResultVC + WmcNavigatorProtocol

extension WmcRecognitionResultVC: WmcNavigatorProtocol {
    static func navigationPaths() -> [WmcNavigatorManager.Path] {
        return [.recognitionResult]
    }

    static func willMakeNavigationVC(with parms: WmcNavigatorManager.Parms) -> UIViewController {
        var vm = WmcRecognitionResultVM()
        if let viewModel = parms.context as? WmcRecognitionResultVM {
            vm = viewModel
        }
        let vc = WmcRecognitionResultVC(vm)
        return vc
    }
}

// MARK: - 扩展WmcRecognitionResultVC + WmcVMProtocol

extension WmcRecognitionResultVC: WmcVMProtocol {
    typealias VMType = WmcRecognitionResultVM
}

// MARK: - [WmcRecognitionResultVC]

class WmcRecognitionResultVC: WmcBaseVC {
    // Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        viewModel.updateCount(0)
        descView.bindModel(viewModel.model)
        updateImageLayout()
        loadData()
    }

    // Internal

    override func makeUI() {
        view.addSubview(contentView)
        view.addSubview(retakeBtn)
        view.addSubview(replenishBtn)
        view.addSubview(saveBtn)

        contentView.addSubview(imgScrollView)
        contentView.addSubview(descView)
        imgScrollView.addSubview(imgContentView)

        let contentViewTop = isIphoneX ? Wmc_safeAreaTop : -20
        contentView.snp.makeConstraints { make in
            make.top.equalTo(contentViewTop)
            make.left.right.equalToSuperview()
            make.bottom.equalTo(retakeBtn.snp.top)
        }

        imgScrollView.snp.makeConstraints { make in
            make.top.left.right.equalToSuperview()
            make.bottom.equalTo(descView.snp.top)
        }

        let descViewBottom = isIphoneX ? -36 : -20
        descView.snp.makeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.bottom.equalTo(descViewBottom)
        }

        let bottom = isIphoneX ? -32 : -5

        retakeBtn.snp.makeConstraints { make in
            make.left.equalTo(17)
            make.bottom.equalTo(bottom)
            make.width.equalTo(50)
            make.height.equalTo(56)
        }

        replenishBtn.snp.makeConstraints { make in
            make.left.equalTo(retakeBtn.snp.right).offset(25)
            make.bottom.width.height.equalTo(retakeBtn)
        }

        saveBtn.snp.makeConstraints { make in
            make.right.equalTo(-17)
            make.bottom.width.height.equalTo(retakeBtn)
        }

        imgContentView.snp.makeConstraints { make in
            make.left.right.top.bottom.equalToSuperview()
        }

        view.layoutIfNeeded()

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            self.imgContentView.center = CGPoint(x: self.imgScrollView.bounds.width / 2.0, y: (self.imgScrollView.bounds.height - 20) / 2.0)
            UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseOut) {
                self.imgContentView.alpha = 1.0
            }
            // 显示裁剪框
            self.imgContentView.showCropViewDefalutRange()
        }
    }

    override func bindViewAction() {
        imgContentView.updateCount = { [weak self] count in
            guard let weakSelf = self else { return }
            weakSelf.viewModel.updateCount(count)
            weakSelf.descView.updateCount(count)
            weakSelf.viewModel.isCorrected = true
        }
        retakeBtn.yp.addEvent { [weak self] _ in
            guard let weakSelf = self else { return }
            weakSelf.navigationController?.popViewController(animated: true)
        }

        replenishBtn.yp.addEvent { [weak self] _ in
            guard let weakSelf = self else { return }

            let view = WmcRecognitionSettingsView.showInView(weakSelf.view, model: weakSelf.viewModel.model)
            view.confirmClosure = { [weak self] model in
                guard let weakSelf = self else { return }
                let oldImgRect = weakSelf.imgContentView.queryImgViewFrame()
                let oldCropRect = weakSelf.imgContentView.queryCropViewFrame()
                // 设置显示文案
                weakSelf.descView.bindModel(model)
                // 刷新图片显示区域
                weakSelf.updateImageLayout()
                // 缩放到1比1
                weakSelf.imgScrollView.setZoomScale(1.0, animated: true)
                
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    weakSelf.imgContentView.center = CGPoint(x: weakSelf.imgScrollView.bounds.width / 2.0, y: (weakSelf.imgScrollView.bounds.height - 20) / 2.0)
                    
                    // 重新设置裁剪区域
                    if oldImgRect.width > 0 {
                        let newImgRect = weakSelf.imgContentView.queryImgViewFrame()
                        let scale = newImgRect.width / oldImgRect.width
                        let rect = CGRect(x: oldCropRect.origin.x * scale, y: oldCropRect.origin.y * scale, width: oldCropRect.width * scale, height: oldCropRect.height * scale)
                        weakSelf.imgContentView.updateCropViewFrame(rect)
                        weakSelf.imgContentView.updateAllMarkViewFrame(scale)
                    }
                }
            }
        }

        saveBtn.yp.addEvent { [weak self] _ in
            guard let weakSelf = self else { return }
            weakSelf.imgContentView.switchPureView(isPure: true)
            weakSelf.descView.setHiddenLogo(false)
            weakSelf.contentView.snp.updateConstraints { make in
                make.top.equalTo(Wmc_safeAreaTop)
            }
            weakSelf.view.layoutIfNeeded()
            let img = weakSelf.saveImageToAlbum(view: weakSelf.contentView)
            weakSelf.viewModel.submitRecognitionResult(image: img)
            weakSelf.viewModel.saveImage(img)
            weakSelf.imgContentView.switchPureView(isPure: false)
            weakSelf.descView.setHiddenLogo(true)
            let contentViewTop = weakSelf.isIphoneX ? Wmc_safeAreaTop : -20
            weakSelf.contentView.snp.updateConstraints { make in
                make.top.equalTo(contentViewTop)
            }
        }
    }

    // Private

    private lazy var contentView: UIView = {
        let view = UIView()
        view.backgroundColor = .wmc_white_FFFFFF
        return view
    }()

    private lazy var imgScrollView: UIScrollView = {
        let view = UIScrollView()
        view.delegate = self
        view.backgroundColor = .wmc_gray_F7F8FA
        view.maximumZoomScale = 3.0
        view.minimumZoomScale = 1.0
        view.bounces = false
        view.showsVerticalScrollIndicator = false
        view.showsHorizontalScrollIndicator = false
        return view
    }()

    private lazy var imgContentView: WmcRecognitionImageView = {
        let view = WmcRecognitionImageView()
        view.alpha = 0.0
        return view
    }()

    private lazy var descView: WmcRecognitionDescView = {
        let view = WmcRecognitionDescView()
        return view
    }()

    private lazy var retakeBtn: WmcTopImgBottomTextBtn = {
        let btn = WmcTopImgBottomTextBtn(title: "重拍", image: "retake_photo_icon".wmc_image)
        btn.font = 12.yp.uiFont(weight: .medium)
        btn.imgTextSpacing = 9
        btn.imgSize = 32
        btn.textColor = .wmc_grayH2_323233
        return btn
    }()

    private lazy var replenishBtn: WmcTopImgBottomTextBtn = {
        let btn = WmcTopImgBottomTextBtn(title: "补充详情", image: "recognition_replenish".wmc_image)
        btn.font = 12.yp.uiFont(weight: .medium)
        btn.imgTextSpacing = 9
        btn.imgSize = 32
        btn.textColor = .wmc_grayH2_323233
        return btn
    }()

    private lazy var saveBtn: WmcTopImgBottomTextBtn = {
        let btn = WmcTopImgBottomTextBtn(title: "保存", image: "uploading_success".wmc_image)
        btn.font = 12.yp.uiFont(weight: .medium)
        btn.imgTextSpacing = 9
        btn.imgSize = 32
        btn.textColor = .wmc_grayH2_323233
        return btn
    }()

    private let isIphoneX = Wmc_safeAreaBottom > 0

    @discardableResult
    private func saveImageToAlbum(view: UIView) -> UIImage? {
        SVProgressHUD.show()
        guard view.bounds.size.width > 0 && view.bounds.size.height > 0 else {
            return nil
        }
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, true, UIScreen.main.scale)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        view.layer.render(in: context)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        SVProgressHUD.dismiss()
        if let image = image {
            UIImageWriteToSavedPhotosAlbum(image, self, #selector(saveImage(image:didFinishSavingWithError:contextInfo:)), nil)
        }
        return image
    }

    @objc
    private func saveImage(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: AnyObject) {
        if error == nil {
            WmcHudManager.toast("图片已保存至系统相册")
        } else {
            WmcHudManager.toast("保存失败")
        }
    }

    private func updateImageLayout() {
        view.layoutIfNeeded()

        if let img = viewModel.image {
            imgContentView.updateImage(img, bounds: imgScrollView.bounds)
        }
    }

    private func loadData() {
        let loadingView = WmcRecognitionLoadingView.showInView(view)

        viewModel.fetchRecognitionInfo { [weak self] list in
            guard let weakSelf = self else { return }
            loadingView.dismiss()

            weakSelf.descView.bindModel(weakSelf.viewModel.model)
            
            if list.isEmpty {
                WmcHudManager.toast("暂无识别结果")
                DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
                    weakSelf.showTip()
                })
                return
            }
            
            weakSelf.showTip()

            // 标记
            weakSelf.imgContentView.showRecognitionResult(list: weakSelf.viewModel.dataSource, radius: weakSelf.viewModel.radius)

            // 显示裁剪框
            weakSelf.imgContentView.showCropViewDefalutRange()

        } failure: { error in
            loadingView.dismiss()
            
            if YPNetworkReachability.queryNetworkReachabilityType() == .notReachable {
                WmcHudManager.toast("网络异常，请稍后重试")
            } else {
                WmcHudManager.toast("暂无识别结果")
            }
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
                self.showTip()
            })
        }
    }
    
    private func showTip() {
        if !viewModel.queryUserTip() {
            let tipView = WmcRecognitionTipView()
            addSubview(tipView)
            
            var config = WmcPresentVC.Config.init(style: .alert(), contentView: tipView, contentLayoutBlock: { make in
                make.center.equalToSuperview()
                make.width.equalTo(320)
                make.height.equalTo(318)
            })
            
            config.isTouchMaskDismiss = false

            let presentVC = WmcPresentVC(config: config)
            presentVC.show()

            WmcUserdefault.save(value: true, forKey: .Alert.Recognition.newUserTip)
        }
    }
}

// MARK: - UIScrollViewDelegate

extension WmcRecognitionResultVC: UIScrollViewDelegate {
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return imgContentView
    }

    func scrollViewDidZoom(_ scrollView: UIScrollView) {
        if scrollView.zoomScale <= 1.0 {
            imgContentView.center = CGPoint(x: scrollView.bounds.width / 2.0, y: (scrollView.bounds.height - 20) / 2.0)
        }

        /*
         viewModel.zoomScale = scrollView.zoomScale

         let boundsSize = scrollView.bounds.size
         var frameToCenter = imgContentView.frame
         let widthDiff = boundsSize.width - frameToCenter.size.width
         let heightDiff = boundsSize.height - frameToCenter.size.height
         frameToCenter.origin.x = (widthDiff > 0) ? widthDiff / 2 : 0
         frameToCenter.origin.y = (heightDiff > 0) ? heightDiff / 2 : 0
         imgContentView.frame = frameToCenter
          */
    }
}
